// 原型链基本关系图演示

// 1. 定义一个构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 2. 在原型上添加方法
Person.prototype.sayHello = function () {
  console.log(`Hello, my name is ${this.name}`);
};

Person.prototype.getAge = function () {
  return this.age;
};

// 3. 创建实例
const person1 = new Person('Alice', 25);
const person2 = new Person('Bob', 30);

// 4. 演示原型链关系
console.log('=== 原型链基本关系图 ===');

// 实例与构造函数的关系
console.log('1. 实例与构造函数的关系:');
console.log('person1.constructor === Person:', person1.constructor === Person); // true
console.log('person1 instanceof Person:', person1 instanceof Person); // true

// 实例与原型的关系
console.log('\n2. 实例与原型的关系:');
console.log('Person.prototype:', Person.prototype);
console.log('person1.__proto__ === Person.prototype:', person1.__proto__ === Person.prototype); // true
console.log(
  'Object.getPrototypeOf(person1) === Person.prototype:',
  Object.getPrototypeOf(person1) === Person.prototype,
); // true

// 原型链的继承关系
console.log('\n3. 原型链的继承关系:');
console.log(
  'Person.prototype.__proto__ === Object.prototype:',
  Person.prototype.__proto__ === Object.prototype,
); // true
console.log('Object.prototype.__proto__:', Object.prototype.__proto__); // null

// 方法调用演示
console.log('\n4. 方法调用演示:');
person1.sayHello(); // 通过原型链调用
person2.sayHello();

// 5. 检查属性来源
console.log('\n5. 属性来源检查:');
console.log('person1.hasOwnProperty("name"):', person1.hasOwnProperty('name')); // true
console.log('person1.hasOwnProperty("sayHello"):', person1.hasOwnProperty('sayHello')); // false
console.log(
  'Person.prototype.hasOwnProperty("sayHello"):',
  Person.prototype.hasOwnProperty('sayHello'),
); // true

// 6. 原型链图示说明
console.log('\n6. 原型链图示:');
console.log('person1 → Person.prototype → Object.prototype → null');
console.log('    ↓         ↓               ↓');
console.log('  实例       原型          Object原型');

// 7. 完整的原型链验证
console.log('\n7. 完整的原型链验证:');
let current = person1;
const chain = [];
while (current) {
  chain.push(current.constructor.name || 'Anonymous');
  current = Object.getPrototypeOf(current);
}
console.log('原型链:', chain.join(' → '));

// 8. 添加自定义原型方法演示继承
Person.prototype.introduce = function () {
  console.log(`I am ${this.name}, ${this.age} years old.`);
};

console.log('\n8. 动态添加原型方法:');
person1.introduce();
person2.introduce();

// 9. 重写原型方法
Person.prototype.sayHello = function () {
  console.log(`Hi, I'm ${this.name}!`);
};

console.log('\n9. 重写原型方法后:');
person1.sayHello();
person2.sayHello();

console.log('\n=== 原型链演示完成 ===');
